# -*- coding: utf-8 -*-
"""
Markdown转换器
支持 Markdown、HTML、Word 等格式的互转
"""

import os
import markdown
import markdown2
from pathlib import Path
from docx import Document
from docx.shared import Pt, RGBColor, Inches
from docx.enum.text import WD_ALIGN_PARAGRAPH
from bs4 import BeautifulSoup
import html2text
import pypandoc


class MarkdownConverter:
    """Markdown转换器类"""

    def __init__(self):
        pass

    def convert(self, input_path, output_dir, conversion_type):
        """
        转换Markdown
        :param input_path: 输入文件路径
        :param output_dir: 输出目录
        :param conversion_type: 转换类型
        :return: 输出文件路径
        """
        if conversion_type == 'md_to_html':
            return self.md_to_html(input_path, output_dir)
        elif conversion_type == 'md_to_word':
            return self.md_to_word(input_path, output_dir)
        elif conversion_type == 'html_to_md':
            return self.html_to_md(input_path, output_dir)
        elif conversion_type == 'word_to_md':
            return self.word_to_md(input_path, output_dir)
        else:
            raise ValueError(f"不支持的转换类型: {conversion_type}")

    def md_to_html(self, md_path, output_dir):
        """
        Markdown转HTML
        :param md_path: Markdown文件路径
        :param output_dir: 输出目录
        :return: 输出文件路径
        """
        if not os.path.exists(md_path):
            raise FileNotFoundError(f"文件不存在: {md_path}")

        if not md_path.lower().endswith('.md'):
            raise ValueError(f"不是Markdown文件: {md_path}")

        base_name = os.path.splitext(os.path.basename(md_path))[0]
        output_path = os.path.join(output_dir, f"{base_name}.html")

        print(f"\n开始转换: {os.path.basename(md_path)}")
        print("=" * 60)

        try:
            # 读取Markdown文件
            with open(md_path, 'r', encoding='utf-8') as f:
                md_content = f.read()

            # 使用markdown2转换（支持更多扩展）
            html_content = markdown2.markdown(
                md_content,
                extras=[
                    'fenced-code-blocks',  # 代码块
                    'tables',              # 表格
                    'break-on-newline',    # 换行
                    'code-friendly',       # 代码友好
                    'header-ids',          # 标题ID
                    'task_list',           # 任务列表
                    'strike',              # 删除线
                ]
            )

            # 生成完整HTML文档
            full_html = f"""<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>{base_name}</title>
    <style>
        body {{
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Microsoft YaHei', sans-serif;
            line-height: 1.6;
            max-width: 800px;
            margin: 0 auto;
            padding: 20px;
            color: #333;
        }}
        h1, h2, h3, h4, h5, h6 {{
            margin-top: 24px;
            margin-bottom: 16px;
            font-weight: 600;
            line-height: 1.25;
        }}
        h1 {{ font-size: 2em; border-bottom: 1px solid #eaecef; padding-bottom: 0.3em; }}
        h2 {{ font-size: 1.5em; border-bottom: 1px solid #eaecef; padding-bottom: 0.3em; }}
        code {{
            background-color: #f6f8fa;
            padding: 0.2em 0.4em;
            border-radius: 3px;
            font-family: 'Consolas', 'Monaco', monospace;
            font-size: 85%;
        }}
        pre {{
            background-color: #f6f8fa;
            padding: 16px;
            border-radius: 6px;
            overflow: auto;
        }}
        pre code {{
            background-color: transparent;
            padding: 0;
        }}
        table {{
            border-collapse: collapse;
            width: 100%;
            margin: 16px 0;
        }}
        table th, table td {{
            border: 1px solid #dfe2e5;
            padding: 6px 13px;
        }}
        table th {{
            background-color: #f6f8fa;
            font-weight: 600;
        }}
        blockquote {{
            border-left: 4px solid #dfe2e5;
            padding-left: 16px;
            color: #6a737d;
            margin: 16px 0;
        }}
        a {{
            color: #0366d6;
            text-decoration: none;
        }}
        a:hover {{
            text-decoration: underline;
        }}
        img {{
            max-width: 100%;
            height: auto;
        }}
    </style>
</head>
<body>
{html_content}
</body>
</html>"""

            # 保存HTML文件
            with open(output_path, 'w', encoding='utf-8') as f:
                f.write(full_html)

            print("✓ Markdown转HTML成功")
            return output_path

        except Exception as e:
            print(f"✗ 转换失败: {str(e)}")
            raise Exception(f"Markdown转HTML失败: {str(e)}")

    def md_to_word(self, md_path, output_dir):
        """
        Markdown转Word
        :param md_path: Markdown文件路径
        :param output_dir: 输出目录
        :return: 输出文件路径
        """
        if not os.path.exists(md_path):
            raise FileNotFoundError(f"文件不存在: {md_path}")

        base_name = os.path.splitext(os.path.basename(md_path))[0]
        output_path = os.path.join(output_dir, f"{base_name}.docx")

        print(f"\n开始转换: {os.path.basename(md_path)}")
        print("=" * 60)

        # 方法1: 使用pandoc（最佳质量）
        try:
            print("方法1: 使用 pandoc - 最佳质量...")
            pypandoc.convert_file(
                md_path,
                'docx',
                outputfile=output_path,
                extra_args=[
                    '--standalone',
                    '--reference-doc=default'
                ]
            )

            if os.path.exists(output_path) and os.path.getsize(output_path) > 500:
                print("✓ pandoc转换成功")
                return output_path
        except Exception as e:
            print(f"✗ pandoc不可用: {str(e)}")

        # 方法2: 使用python-docx手动转换
        try:
            print("\n方法2: 使用 python-docx 手动转换...")

            # 读取Markdown内容
            with open(md_path, 'r', encoding='utf-8') as f:
                md_content = f.read()

            # 转换为HTML
            html_content = markdown2.markdown(
                md_content,
                extras=['fenced-code-blocks', 'tables']
            )

            # 解析HTML
            soup = BeautifulSoup(html_content, 'html.parser')

            # 创建Word文档
            doc = Document()

            # 遍历HTML元素并转换为Word
            for element in soup.find_all(['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'p', 'pre', 'ul', 'ol', 'table']):
                if element.name.startswith('h'):
                    # 标题
                    level = int(element.name[1])
                    heading = doc.add_heading(element.get_text().strip(), level=level)
                elif element.name == 'p':
                    # 段落
                    doc.add_paragraph(element.get_text().strip())
                elif element.name == 'pre':
                    # 代码块
                    code_para = doc.add_paragraph(element.get_text())
                    code_para.style = 'No Spacing'
                    for run in code_para.runs:
                        run.font.name = 'Consolas'
                        run.font.size = Pt(9)
                elif element.name in ['ul', 'ol']:
                    # 列表
                    for li in element.find_all('li'):
                        doc.add_paragraph(
                            li.get_text().strip(),
                            style='List Bullet' if element.name == 'ul' else 'List Number'
                        )
                elif element.name == 'table':
                    # 表格
                    rows = element.find_all('tr')
                    if rows:
                        cols = len(rows[0].find_all(['th', 'td']))
                        table = doc.add_table(rows=len(rows), cols=cols)
                        table.style = 'Light Grid Accent 1'

                        for i, row in enumerate(rows):
                            cells = row.find_all(['th', 'td'])
                            for j, cell in enumerate(cells):
                                table.rows[i].cells[j].text = cell.get_text().strip()

            doc.save(output_path)
            print("✓ python-docx转换成功")
            return output_path

        except Exception as e:
            print(f"✗ 转换失败: {str(e)}")
            raise Exception(f"Markdown转Word失败: {str(e)}")

    def html_to_md(self, html_path, output_dir):
        """
        HTML转Markdown
        :param html_path: HTML文件路径
        :param output_dir: 输出目录
        :return: 输出文件路径
        """
        if not os.path.exists(html_path):
            raise FileNotFoundError(f"文件不存在: {html_path}")

        base_name = os.path.splitext(os.path.basename(html_path))[0]
        output_path = os.path.join(output_dir, f"{base_name}.md")

        print(f"\n开始转换: {os.path.basename(html_path)}")
        print("=" * 60)

        try:
            # 读取HTML文件
            with open(html_path, 'r', encoding='utf-8') as f:
                html_content = f.read()

            # 使用html2text转换
            h = html2text.HTML2Text()
            h.ignore_links = False
            h.ignore_images = False
            h.ignore_tables = False
            h.body_width = 0  # 不自动换行

            md_content = h.handle(html_content)

            # 保存Markdown文件
            with open(output_path, 'w', encoding='utf-8') as f:
                f.write(md_content)

            print("✓ HTML转Markdown成功")
            return output_path

        except Exception as e:
            print(f"✗ 转换失败: {str(e)}")
            raise Exception(f"HTML转Markdown失败: {str(e)}")

    def word_to_md(self, word_path, output_dir):
        """
        Word转Markdown
        :param word_path: Word文件路径
        :param output_dir: 输出目录
        :return: 输出文件路径
        """
        if not os.path.exists(word_path):
            raise FileNotFoundError(f"文件不存在: {word_path}")

        base_name = os.path.splitext(os.path.basename(word_path))[0]
        output_path = os.path.join(output_dir, f"{base_name}.md")

        print(f"\n开始转换: {os.path.basename(word_path)}")
        print("=" * 60)

        # 方法1: 使用pandoc（最佳质量）
        try:
            print("方法1: 使用 pandoc - 最佳质量...")
            pypandoc.convert_file(
                word_path,
                'markdown',
                outputfile=output_path,
                extra_args=['--wrap=none']
            )

            if os.path.exists(output_path) and os.path.getsize(output_path) > 0:
                print("✓ pandoc转换成功")
                return output_path
        except Exception as e:
            print(f"✗ pandoc不可用: {str(e)}")

        # 方法2: 使用python-docx手动提取
        try:
            print("\n方法2: 使用 python-docx 手动提取...")

            doc = Document(word_path)
            md_lines = []

            for para in doc.paragraphs:
                text = para.text.strip()
                if not text:
                    md_lines.append('')
                    continue

                # 判断是否为标题
                if para.style.name.startswith('Heading'):
                    level = int(para.style.name.split()[-1]) if para.style.name.split()[-1].isdigit() else 1
                    md_lines.append(f"{'#' * level} {text}")
                else:
                    md_lines.append(text)

            # 处理表格
            for table in doc.tables:
                md_lines.append('')
                for i, row in enumerate(table.rows):
                    cells = [cell.text.strip() for cell in row.cells]
                    md_lines.append('| ' + ' | '.join(cells) + ' |')

                    # 添加表头分隔线
                    if i == 0:
                        md_lines.append('| ' + ' | '.join(['---'] * len(cells)) + ' |')

                md_lines.append('')

            # 保存Markdown文件
            with open(output_path, 'w', encoding='utf-8') as f:
                f.write('\n'.join(md_lines))

            print("✓ python-docx转换成功")
            return output_path

        except Exception as e:
            print(f"✗ 转换失败: {str(e)}")
            raise Exception(f"Word转Markdown失败: {str(e)}")
